package com.loe.ktui.other

import android.content.Context
import android.content.res.TypedArray
import android.graphics.Color
import android.graphics.drawable.GradientDrawable
import android.util.AttributeSet
import androidx.core.content.res.*
import com.loe.ktui.KtFrameLayout
import com.loe.ktui.R
import com.loe.ktui.ktPx
import com.loe.ktui.ktSafe
import com.loe.ktui.util.UiShape

class ShapeView : KtFrameLayout
{
    constructor(context: Context) : super(context)
    {
        initXML()
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
    {
        initXML(context.obtainStyledAttributes(attrs, R.styleable.ShapeView))
    }

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
    {
        initXML(context.obtainStyledAttributes(attrs, R.styleable.ShapeView, defStyleAttr, 0))
    }

    private fun initXML(typedArray: TypedArray? = null)
    {
        typedArray?.let()
        {
            ktSafe()
            {
                type = when (it.getIntOrThrow(R.styleable.ShapeView_shape_type))
                {
                    1 -> "line"
                    2 -> "ring"
                    3 -> "oval"
                    else -> "rect"
                }
            }
            ktSafe { corner = it.getDimensionOrThrow(R.styleable.ShapeView_shape_corner) }
            ktSafe { corners = it.getStringOrThrow(R.styleable.ShapeView_shape_corners).split(",").map { ktPx(it.toDouble()).toFloat() }.toTypedArray() }

            ktSafe { color = it.getColorOrThrow(R.styleable.ShapeView_shape_color) }
            ktSafe()
            {
                colors = it.getStringOrThrow(R.styleable.ShapeView_shape_colors).split(",").map { Color.parseColor(it) }.toTypedArray()
                gradient = when (it.getInt(R.styleable.ShapeView_shape_gradient, 0))
                {
                    1 -> "radial"
                    2 -> "sweep"
                    else -> "linear"
                }
                ktSafe { centerX = it.getFloatOrThrow(R.styleable.ShapeView_shape_centerX).toDouble() }
                ktSafe { centerY = it.getFloatOrThrow(R.styleable.ShapeView_shape_centerY).toDouble() }

                gradientAngle = it.getInt(R.styleable.ShapeView_shape_gradientAngle, 0)
                ktSafe { gradientRadius = it.getDimensionOrThrow(R.styleable.ShapeView_shape_gradientRadius) }
            }

            ktSafe()
            {
                strokeColor = it.getColorOrThrow(R.styleable.ShapeView_shape_strokeColor)
                strokeWidth = it.getDimension(R.styleable.ShapeView_shape_strokeWidth, 1f)
                strokeDash = it.getDimension(R.styleable.ShapeView_shape_strokeDash, 0f)
                strokeGap = it.getDimension(R.styleable.ShapeView_shape_strokeGap, ktPx(2.0).toFloat())
            }
        }

        background = createDrawable()
    }

    fun setShape(block: (UiShape.() -> Unit)? = null)
    {
        val shape = UiShape()
        block?.let { shape.it() }
        background = shape.createDrawable()
    }

    /** 类型：rect  line  ring  oval */
    var type: String? = null

    /** 圆角*/
    var corner: Float? = null
    var corners: Array<Float>? = null

    /** 颜色 */
    var color: Int? = null
    var colors: Array<Int>? = null

    /** 边框*/
    var strokeWidth: Float? = null
    var strokeColor: Int? = null
    var strokeDash: Float? = null
    var strokeGap: Float? = null

    /** 中心 */
    var centerX: Double? = null
    var centerY: Double? = null

    /** 渐变：linear  radial  sweep */
    var gradient: String? = null
    var gradientRadius: Float? = null
    var gradientAngle: Int? = null

    /** 创建Drawable */
    fun createDrawable(): GradientDrawable
    {
        val drawable = GradientDrawable()

        drawable.shape = when (type)
        {
            "line" -> GradientDrawable.LINE
            "ring" -> GradientDrawable.RING
            "oval" -> GradientDrawable.OVAL
            else -> GradientDrawable.RECTANGLE
        }

        corner?.let { drawable.cornerRadius = it }
        corners?.let {
            val cs = FloatArray(8) { 0f }
            it[0].let { cs[0] = it; cs[1] = it }
            it[1].let { cs[2] = it; cs[3] = it }
            it[2].let { cs[4] = it; cs[5] = it }
            it[3].let { cs[6] = it; cs[7] = it }
            drawable.cornerRadii = cs
        }

        color?.let { drawable.setColor(it) }
        colors?.let { drawable.colors = it.toIntArray() }

        strokeColor?.let {
            val dash = strokeDash
            val gap = if (strokeGap != null) strokeGap else dash
            if(dash == null || dash == 0f)
            {
                drawable.setStroke(strokeWidth?.toInt() ?: 1, it)
            }else
            {
                drawable.setStroke(strokeWidth?.toInt() ?: 1, it, dash ?: 6f, gap ?: 6f)
            }
        }

        if (centerX != null && centerY != null)
        {
            drawable.setGradientCenter(centerX!!.toFloat(), centerY!!.toFloat())
        }

        gradient?.let {
            drawable.gradientType = when (it)
            {
                "radial" ->
                {
                    gradientRadius?.let { drawable.gradientRadius = it }
                    GradientDrawable.RADIAL_GRADIENT
                }
                "sweep" -> GradientDrawable.SWEEP_GRADIENT
                else -> GradientDrawable.LINEAR_GRADIENT
            }
        }

        gradientAngle?.let {
            val angle = ((it + 360) % 360)
            drawable.orientation = when (angle / 45)
            {
                7 -> GradientDrawable.Orientation.TL_BR
                6 -> GradientDrawable.Orientation.TOP_BOTTOM
                5 -> GradientDrawable.Orientation.TR_BL
                4 -> GradientDrawable.Orientation.RIGHT_LEFT
                3 -> GradientDrawable.Orientation.BR_TL
                2 -> GradientDrawable.Orientation.BOTTOM_TOP
                1 -> GradientDrawable.Orientation.BL_TR
                else -> GradientDrawable.Orientation.LEFT_RIGHT
            }
        }

        return drawable
    }
}
